// ============================================================================================================================================
//
//
//
//
// 溶解模块
//
//
//
//
// ============================================================================================================================================
#ifndef UNITY_SHADER_DT_DISSOLVE_UTIL_INCLUDED
#define UNITY_SHADER_DT_DISSOLVE_UTIL_INCLUDED
        // ==================================================================
        // 引用
        // ==================================================================
        //  #include "XXXXXX.hlsl"
        // ==================================================================
        // 溶解函数
        //     溶解:特效溶解模块的所有功能
        //     结构体: DissolveResult
        //     函数:
        //          基础溶解
        //          DissolveResult dissResult = CalcDissolveResult(bool ison, float data, float _Factor);、        
        //          可调溶解边
        //          DissolveResult dissResult = CalcDissolveResult_S(bool ison, float data, float _Factor, float _Soft);
        //          可调溶解边+溶解边扭曲
        //          DissolveResult dissResult = CalcDissolveResult_SD(bool ison, float data, float _Factor, float _Soft
        //                                                      DistDistortResult _DistResult);
        //          可调溶解边+溶解描边
        //          DissolveResult dissResult = CalcDissolveResult_SW(bool ison, float data, float _Factor, float _Soft, 
        //                                                      float _Wide, float4 _EdgeColor);
        //          可调溶解边+溶解描边+溶解边扭曲
        //          DissolveResult dissResult = CalcDissolveResult_SWD(bool ison, float data, float _Factor, float _Soft, 
        //                                                      float _Wide, float4 _EdgeColor, DistDistortResult _DistResult);
        //          应用
        //          ApplyDissolveEffect(DissolveResult _Result, bool isOn, inout float3 _FColor, inout float _FAlpha)
        // ==================================================================
        #ifdef DT_USE_OPTIMIZE
            #define DT_USE_SELF_DISS //使用自己的溶解 
        #endif

        // ================================================================== 
        // 结构体  
        // ================================================================== 

        // 输出的结果
        struct DissolveResult
        {
            float Alpha;//DissolveValue; //溶解值
            float Edge; //溶解边缘
            float3 EdgeColor; //溶解边缘颜色
        };
 
        // ==================================================================
        // 计算
        //     调用这个函数，就可以得到溶解的结果
        // ==================================================================
        DissolveResult CalcDissolveResult(float _isOn, float _InputData,float _Factor)
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            { 
                float finalAlpha = 1;
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0; //把贴图色从0-1 => 1-2
                float _factor = saturate(_Factor) * 2.0 ; //溶解因子 0-1 => 0 - 2
                Outresult.Alpha = saturate(_inputData - _factor);
            }
            return Outresult;
        } 

        DissolveResult CalcDissolveResult_S(float _isOn, float _InputData, float _Factor,float _Soft)
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            {
                float finalAlpha = 1;
                //把贴图色从0-1 => 1-2
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0;
                //羽化因子    
                float _soft = clamp(_Soft, 0.01, 0.99);
                //溶解因子 0-1 => 0 - 2    
                float _factor = saturate(_Factor) ;  
                _factor *= 2.0 - _soft; 
                float tmpV = _inputData - _factor; //基础溶解
                finalAlpha = smoothstep(_soft, 1.0, tmpV); //softvalue            
                Outresult.Alpha = saturate(finalAlpha); 
            }
            return Outresult;
        }

        DissolveResult CalcDissolveResult_SD(float _isOn, float _InputData, float _Factor,float _Soft,DistortResult _DistResult)
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            {
                float finalAlpha = 1;
                //把贴图色从0-1 => 1-2
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0;
                //羽化因子    
                float _soft = clamp(_Soft, 0.01, 0.99);
                //溶解因子 0-1 => 0 - 2    
                float _factor = saturate(_Factor) ;  
                _factor *= 2.0 - _soft; 
                float tmpV = _inputData - _factor; //基础溶解
                finalAlpha = smoothstep(_soft, 1.0, tmpV); //softvalue
                AppendDistortResultV1(_DistResult, /*inout*/finalAlpha);         
                Outresult.Alpha = saturate(finalAlpha); 
            }
            return Outresult;
        }

        DissolveResult CalcDissolveResult_SW(float _isOn, float _InputData, float _Factor,
            float _Soft, float _Wide, float4 _EdgeColor)
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            {                 
                float finalAlpha = 1;
                float finalEdge = 0;
                
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0; //把贴图色从0-1 => 1-2
                
                float _factor/*Input*/ = _Factor ; //溶解因子 0-1 => 0 - 2 => 0 - -2【规避减法】  

                
                float _soft = clamp(_Soft, 0.001, 0.999);
                float _wide = saturate(_Wide);              
                    
                #if defined(DT_USE_SELF_DISS) 
                    _factor = dt_Ramp_float(_factor, 0.0, 1.0, -_wide, 1.0);
                    _factor *= 2.0 - _soft;
                #else
                    _factor *= 2.0;
                #endif

                float tmpV = _inputData - _factor; //基础溶解
                finalAlpha = smoothstep(_soft, 1.0, tmpV); //softvalue

                #if defined(DT_USE_SELF_DISS)
                    finalEdge = smoothstep(_soft, 1.0, tmpV - _wide);// * step(0.000001, _wide); //edge
                    finalEdge = _wide > 0.000001 ? finalEdge : 1;
                #else
                    _wide = clamp(_Wide, 0.001, 0.999); 
                    finalEdge = smoothstep(_wide - _soft * 0.5, _wide, finalAlpha);
                #endif
                finalEdge = 1.0 - finalEdge;

                Outresult.Alpha = saturate(finalAlpha);
                Outresult.Edge = saturate(finalEdge);
                Outresult.EdgeColor = _EdgeColor.rgb * _EdgeColor.a;            
            }
            return Outresult;
        }

        DissolveResult CalcDissolveResult_SWD(float _isOn, float _InputData, 
            float _Factor,float _Soft, float _Wide, float4 _EdgeColor,
            DistortResult _DistResult) 
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            {            
                Outresult.EdgeColor = _EdgeColor.rgb * _EdgeColor.a;

                float finalAlpha = 1;
                float finalEdge = 0;
                
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0; //把贴图色从0-1 => 1-2
                float _factor/*Input*/ = _Factor ; //溶解因子 0-1 => 0 - 2 => 0 - -2【规避减法】  

                
                float _soft = clamp(_Soft, 0.001, 0.999);
                float _wide = saturate(_Wide);              
                    
                #if defined(DT_USE_SELF_DISS) 
                    _factor = dt_Ramp_float(_factor, 0.0, 1.0, -_wide, 1.0);
                    _factor *= 2.0 - _soft;
                #else            
                    _factor *= 2.0;
                #endif

                float tmpV = _inputData - _factor; //基础溶解
                //finalAlpha = _inputData - _factor;
                finalAlpha = smoothstep(_soft, 1.0, tmpV); //softvalue 

                #if defined(DT_USE_SELF_DISS)
                    finalEdge = smoothstep(_soft, 1.0, tmpV - _wide);// * step(0.000001, _wide); //edge
                    finalEdge = _wide > 0.000001 ? finalEdge : 1;
                #else
                    _wide = clamp(_Wide,0.001, 0.999);
                    finalEdge = smoothstep(_wide - _soft * 0.5, _wide, finalAlpha);
                #endif
                finalEdge = 1.0 - finalEdge;

                // 扰动
                AppendDistortResultV1(_DistResult, /*inout*/finalAlpha);
                // AppendDistortResultV1(_DistResult, /*inout*/finalEdge);

                //此处需要限定到0-1，因为这里其实在计算的还是颜色，不可控的溢出是不理智的。
                //下面赋值时会 saturate，所以这里省略
                Outresult.Alpha = saturate(finalAlpha);
                Outresult.Edge = saturate(finalEdge);
            } 
            return Outresult;
        }

        DissolveResult CalcDissolveResultBase(float _isOn, float _InputData, 
            float _Factor,float _Soft, float _Wide, float4 finalEdgeColor,
            float _DistResult, float _DistFactor)
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            {            
                Outresult.EdgeColor = finalEdgeColor.rgb * finalEdgeColor.a;

                float finalAlpha = 1;
                float finalEdge = 0;
                
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0; //把贴图色从0-1 => 1-2
                float _factor/*Input*/ = _Factor ; //溶解因子 0-1 => 0 - 2 => 0 - -2【规避减法】  

                
                float _soft = clamp(_Soft, 0.01, 0.99);
                float _wide = saturate(_Wide);              
                    
                #if defined(DT_USE_SELF_DISS) 
                    _factor = dt_Ramp_float(_factor, 0.0, 1.0, -_wide, 1.0);
                    _factor *= 2.0 - _soft;
                #else            
                    _factor *= 2.0;
                #endif

                float tmpV = _inputData - _factor; //基础溶解
                //finalAlpha = _inputData - _factor;
                finalAlpha = smoothstep(_soft, 1.0, tmpV); //softvalue 

                #if defined(DT_USE_SELF_DISS)
                    finalEdge = smoothstep(_soft, 1.0, tmpV - _wide);// * step(0.000001, _wide); //edge
                    finalEdge = _wide > 0.000001 ? finalEdge : 1;
                #else
                    _wide = clamp(_Wide,0.01, 0.99); 
                    finalEdge = smoothstep(_wide - _soft * 0.5, _wide, finalAlpha);
                #endif
                finalEdge = 1.0 - finalEdge;

                // 扰动
                DistortResult dstR = InitDistortResult(_DistResult, _DistFactor);
                AppendDistortResultV1(dstR, finalAlpha);

                //此处需要限定到0-1，因为这里其实在计算的还是颜色，不可控的溢出是不理智的。
                //下面赋值时会 saturate，所以这里省略
                Outresult.Alpha = saturate(finalAlpha);
                Outresult.Edge = saturate(finalEdge);
            } 
            return Outresult;
        }
        // ==================================================================
        // 调用
        //     color: 最终的颜色
        //     alpha: 最终的透明度
        //     调用这个函数，就可以得到溶解的结果
        // ==================================================================
        void ApplyDissolveEffect(float _isOn, DissolveResult result, inout float3 color,inout float alpha)
        {
            // UNITY_BRANCH
            if(_isOn > 0.5)
            {
                color = lerp(color, result.EdgeColor, result.Edge); 
                alpha *= result.Alpha;
                //小于0的颜色是不可控的。无特殊要求不允许颜色小于 0 
                color = max(0.0, color);
                //小于0或大于1的透明是不可控的。无特殊要求不允许透明溢出[0-1]的范围 
                alpha = saturate(alpha);
            }
        }
#endif // UNITY_SHADER_DT_DISSOLVE_UTIL_INCLUDED